#!/bin/bash

# 一键自动化打包上传到服务器
# 项目主页： https://gitee.com/xrootx/fydeploy

VERSION=v1.1.0
# 20211104，Karamay

# 环境依赖：
# STEP 1: 安装SSH公钥，实现远程免密登录，既省去了每次输入密码的烦恼，也规避了密码泄露的安全风险。
# 1. ssh-keygen -t rsa	   # 在本机生成rsa签名文件，默认为~/.ssh/id_rsa。如果以前生成过，则可忽略
# 2. ssh-copy-id user@ip   # 将公钥id_rsa.pub复制到远程主机user账号下 

# STEP 2: 采用rsync进行文件传输（下一版本）
# 如果要支持本地忽略模式，本地及远程主机需安装rsync，安装需要root权限。
# rsync可带来另一个好处：支持增量差异化传输，只上传有变化的文件。

# 本地开发电脑（mac）安装 rsync 客户端
# > brew install rsync

# 远程服务器（CentOS） 安装 rsync 服务端
# > sudo yum install rsync
# 启动rsync服务
# > sudo systemctl start rsyncd.service
# > sudo systemctl enable rsyncd.service
# 检查是否已经成功启动
# > netstat -lnp | grep 873

# 打包命令，无需打包则留空
#BUILD_CMD="yarn build"         # 示例：用 yarn build 命令打包
BUILD_CMD=""                 # 示例：无需打包

# 远程主机的ip或主机名称
IP="192.168.50.220"

# 远程主机的SSH端口，默认为22
PORT="22"

# 远程主机用户名
USER="fy"

# 本地文件目录，必须是绝对路径，以/结尾
LOCAL_PATH="/Users/yi/code/shell/jsdeploy/testdcmind/"      # 示例
# LOCAL_PATH=`pwd`"/"                                       # 示例：直接取此脚本所在的路径
# LOCAL_PATH=`pwd`"/dist/"                                  # 示例：此脚本所在的路径下的子目录

########  
# TODO：需忽略的本地文件和目录。必须配合 rsync 使用。下一版本实现。
#######
# LOCAL_IGNORE_DIRS=(file1 file2 dir1 dir2) # 下一版本实现

# 远程主机的发布目录，必须是绝对路径，以/结尾
REMOTE_PATH="/home/fy/tmp2/"            # 示例
#REMOTE_PATH="/opt/fy/app/www/dcmind/"      # 示例

# 是否先清理远程主机的目录，避免文件残留。 true/false ,注意全部小写
# 慎重使用，避免误删 ***********
REMOTE_DELETE=true
# 慎重使用，避免误删 ***********

# 清理时，保留远端的某些文件或目录。支持多个，用空格分割。没有则留空。
# REMOTE_IGNORE_DIRS=(file1 file2 dir1 dir2)    # 示例
REMOTE_IGNORE_DIRS=(bin data log bak)         # 示例
# REMOTE_IGNORE_DIRS=()                           # 示例

########———— 参数结束 ————########——————

echo 
echo "【fydeploy】 "$VERSION

IP=$(echo $IP | xargs)
PORT=$(echo $PORT | xargs)
BUILD_CMD=$(echo $BUILD_CMD | xargs) 
LOCAL_PATH=$(echo $LOCAL_PATH | xargs)
REMOTE_PATH=$(echo $REMOTE_PATH | xargs)

if [ ${#IP} == 0 ]; then echo " **** **** IP 参数不合法，程序退出！**** ****" ; exit 999; fi
if [ ${#PORT} == 0 ]; then echo " **** **** PORT 参数不合法，程序退出！**** ****" ; exit 999; fi
if [ ${#LOCAL_PATH} -lt 3 ]; then echo " **** **** LOCAL_PATH 参数不合法，程序退出！**** ****" ; exit 999; fi
if [ ${#REMOTE_PATH} -lt 3 ]; then echo " **** **** REMOTE_PATH 参数不合法，程序退出！**** ****" ; exit 999; fi

if [ ${#BUILD_CMD} == 0 ]; then
    echo 【无需打包】————————
else
    echo 【开始打包】————————
    echo "  执行命令："$BUILD_CMD
    $BUILD_CMD    # 执行打包指令
    if [ $? != 0 ]; then echo "  **** **** 打包发生异常，程序退出！**** ****" ; echo ; exit 1 ; fi
fi

# 清除远程主机上的旧文件。参考： rm -rf `ls | egrep -v "dir1|dir2"`
if [ $REMOTE_DELETE = true ]; then
    RM_PARM=''
    echo "【清除文件】————————————————" 
    ignore_count=${#REMOTE_IGNORE_DIRS[*]}
    echo "  忽略数量："$ignore_count
    
    REMOTE_CMD="cd "$REMOTE_PATH
    echo $REMOTE_CMD > fydeploy_remote_cmd.tmp
    echo 'if [ $? != 0 ]; then exit 25 ; fi' >> fydeploy_remote_cmd.tmp

    if [ $ignore_count -gt 0 ]; then
        RM_PARM="\`ls | egrep -v \""  # head
        RM_PARM=$RM_PARM${REMOTE_IGNORE_DIRS[0]}  # 先取第一个
        ignore_index=1
        while (( $ignore_index < $ignore_count )) # 循环取后面的
        do
            RM_PARM=$RM_PARM'|'${REMOTE_IGNORE_DIRS[ignore_index]}
            ((ignore_index++))
        done
        RM_PARM=$RM_PARM"\"\`"  # tail
        REMOTE_CMD="rm -rf "$RM_PARM

        echo $REMOTE_CMD >> fydeploy_remote_cmd.tmp
    else
        echo 'rm -rf *' >> fydeploy_remote_cmd.tmp
    fi

    echo "  远程指令："
    cat fydeploy_remote_cmd.tmp
    chmod +x fydeploy_remote_cmd.tmp
    if [ $? != 0 ]; then echo "  **** **** 发生异常，程序退出！**** ****" ; echo ; exit 11 ; fi

    LOCAL_CMD="scp -P "$PORT" -q fydeploy_remote_cmd.tmp "$USER"@"$IP":"$REMOTE_PATH
    echo "  执行命令："$LOCAL_CMD
    $LOCAL_CMD
    if [ $? != 0 ]; then echo "  **** **** 发生异常，程序退出！**** ****" ; echo ; exit 2 ; fi

    LOCAL_CMD="ssh -p "$PORT" "$USER"@"$IP" \""$REMOTE_PATH"fydeploy_remote_cmd.tmp\" "
    echo "  执行命令："$LOCAL_CMD
    $LOCAL_CMD
    if [ $? != 0 ]; then echo "  **** **** 发生异常，程序退出！**** ****" ; echo ; exit 3 ; fi

    rm -f fydeploy_remote_cmd.tmp  
    if [ $? != 0 ]; then echo "  **** **** 发生异常，程序退出！**** ****" ; echo ; exit 4 ; fi
fi

echo "【开始上传】————————————————————————————"

# 【scp方案】
# scp -P $PORT -rqC $LOCAL_PATH $USER@$IP:$REMOTE_PATH
LOCAL_CMD='scp -P '$PORT' -rqC '$LOCAL_PATH'* '$USER'@'$IP':'$REMOTE_PATH
echo '  执行命令：''scp -P '$PORT' -rqC '$LOCAL_PATH'* '$USER'@'$IP':'$REMOTE_PATH
$LOCAL_CMD 
if [ $? != 0 ]; then echo "  **** **** 发生异常，程序退出！**** ****" ; echo ; exit 5 ; fi

# 【rsync方案】下个版本考虑
# echo rsync -avP --exclude={".git"} $LOCAL_PATH $USER@$IP:$PORT$REMOTE_PATH
# rsync -avrP --exclude '.git'  /Users/yi/code/shell/jsdeploy/ fy@192.168.50.220:/home/fy/tmp2/ --port=22 --progress
# 参数： -r --info=progress2 

echo "【成功发布】————— end ———————————————————————————————————"
echo 